iT邦幫忙

2022 iThome 鐵人賽

DAY 8
2

這篇教學會介紹如何使用 OpenCV 裡的單物件追蹤功能 ( tracker ),並搭配 cv2.selectROI 選取需要追蹤的物體,就能即時進行該物件的追蹤。

原文參考:OpenCV 單物件追蹤

因為程式中的 OpenCV 會需要使用鏡頭或 GPU,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda ) ,並安裝 OpenCV 函式庫 ( 參考:OpenCV 函式庫 )。

Python 教學 - OpenCV 單物件追蹤

物件追蹤的八種演算法

OpenCV 提供了八種物件追蹤的演算法,演算法的速度和精準度如下表所示:

演算法 速度 精準度 說明
BOOSTING 元老級追蹤器,速度較慢,並且不是很準確。
MIL 比 BOOSTING 更精確,但仍然不是很準確。
GOTURN 需要搭配深度運算模型才能運作的追蹤器。
TLD 速度普通,精準度普通的追蹤器。
MEDIANFLOW 對於會跳動或快速移動的物件,判斷不是很準確。
KCF 不錯的追蹤器,但在物件被遮蔽的狀態下不是很準確。
MOSSE 最快 速度最快,但精準度比 KCF 和 CSRT 稍差。
CSRT 最高 精準度比 KCF 好,但速度比 KCF 慢。

使用 Python 時創建追蹤器的語法如下:

演算法 創建語法
BOOSTING cv2.TrackerBoosting_create()
MIL cv2.TrackerMIL_create()
GOTURN cv2.TrackerGOTURN_create()
TLD cv2.TrackerTLD_create()
MEDIANFLOW cv2.TrackerMedianFlow_create()
KCF cv2.TrackerKCF_create()
MOSSE cv2.TrackerMOSSE_create()
CSRT cv2.TrackerCSRT_create()

cv2.selectROI 選取特定區域

要進行物件追蹤,必須先選取特定區域,OpenCV 內建 cv2.selectROI 方法可以進行選取的功能,使用方法如下:

area = cv2.selectROI('視窗名稱', frame, showCrosshair=False, fromCenter=False)
# area:(x, y, width, height)
# frame:要選取的影像
# showCrosshair:選取框中間是否要有十字線,預設 True
# fromCenter:True 中心點選取,False 右上角選取

下方的程式碼執行後,按下鍵盤按鍵 a 就會進入選取模式,此時攝影機畫面會暫停,使用滑鼠拖拉選取後,按下 enter 鍵,就會回傳 xy 座標以及長寬尺寸

import cv2

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    ret, frame = cap.read()
    if not ret:
        print("Cannot receive frame")
        break
    keyName = cv2.waitKey(1)
    # 按下 q 結束
    if keyName == ord('q'):
        break
    # 按下 a 開始選取
    if keyName == ord('a'):
        # 選取區域
        area = cv2.selectROI('oxxostudio', frame, showCrosshair=False, fromCenter=False)
        print(area)

    cv2.imshow('oxxostudio', frame)

cap.release()
cv2.destroyAllWindows()

Python 教學 - OpenCV 單物件追蹤

即時追蹤畫面中的特定物體

透過 cv2.selectROI 方法取得區域位置和尺寸後,將位置和尺寸提交給透過 cv2.TrackerCSRT_create() 所創建的追蹤器,搭配 tracker.init 追蹤器初始化以及 tracker.update 追蹤器更新的方法,就能即時追蹤畫面中的特定物體。

下方的程式碼執行後,視窗中會看見攝影機的即時影像,按下鍵盤的 a 後影像會暫停,進入擷取模式,透過滑鼠拖曳出要追蹤的物件區域,按下 Enter 後就會出現紅色追蹤外框,開始追蹤特定的物件。

import cv2

tracker = cv2.TrackerCSRT_create()  # 創建追蹤器
tracking = False                    # 設定 False 表示尚未開始追蹤

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()

while True:
    ret, frame = cap.read()
    if not ret:
        print("Cannot receive frame")
        break
    frame = cv2.resize(frame,(540,300))  # 縮小尺寸,加快速度
    keyName = cv2.waitKey(1)

    if keyName == ord('q'):
        break
    if keyName == ord('a'):
        area = cv2.selectROI('oxxostudio', frame, showCrosshair=False, fromCenter=False)
        tracker.init(frame, area)    # 初始化追蹤器
        tracking = True              # 設定可以開始追蹤
    if tracking:
        success, point = tracker.update(frame)   # 追蹤成功後,不斷回傳左上和右下的座標
        if success:
            p1 = [int(point[0]), int(point[1])]
            p2 = [int(point[0] + point[2]), int(point[1] + point[3])]
            cv2.rectangle(frame, p1, p2, (0,0,255), 3)   # 根據座標,繪製四邊形,框住要追蹤的物件

    cv2.imshow('oxxostudio', frame)

cap.release()
cv2.destroyAllWindows()

Python 教學 - OpenCV 單物件追蹤

更多 Python 教學

大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我已經寫了超過 400 篇 Python 的教學,有興趣可以參考下方連結呦~ ^_^


上一篇
( Day 7 ) OpenCV 辨識不同人臉
下一篇
( Day 9 ) OpenCV 多物件追蹤
系列文
Python x AI 影像辨識好好玩32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言